// rgblink_device.cpp
#include "rgblink_device.h"

RgblinkDevice::RgblinkDevice(RGBlinkProtocolCallback callback, SendBufferFunc sendBuffer, int bufferSize)
{
	this->device_pipe = (Pipe_t*)malloc(sizeof(Pipe_t));
	this->device_buffer = (BYTE*)malloc(bufferSize);
	this->device_Protocol = (RGBlinkProtocol*)malloc(sizeof(RGBlinkProtocol));
	this->_crossDevice = NULL;
	pipe_init(this->device_pipe, this->device_buffer, bufferSize);
	Init_RGBlinkProtocol(this->device_Protocol, this->device_pipe, callback, sendBuffer);
}
RgblinkDevice::~RgblinkDevice()
{
	this->close();
	
	free(this->device_pipe);
	free(this->device_buffer);
	free(this->device_Protocol);
	
	
}

void RgblinkDevice::operator()(char * buf, int bufSize)
{
	this->writeBuf(buf, bufSize);
}

void RgblinkDevice::sendBuf(char * buf, int bufSize)
{
	this->writeBuf(buf, bufSize);
}

CrossDeviceList* RgblinkDevice::getDeviceList(void)
{
	return CrossDevice::getDeviceList();
}

bool RgblinkDevice::open(char* deviceName)
{
	this->close();
	this->_crossDevice = new CrossDevice();
	if(this->_crossDevice->open(deviceName))
	{
		return true;
	}
	delete this->_crossDevice;
	this->_crossDevice = NULL;
	return false;
}
bool RgblinkDevice::close()
{
	if(this->_crossDevice)
	{
		this->_crossDevice->close();
		delete this->_crossDevice;
		this->_crossDevice = NULL;
	}
	return true;
}
void RgblinkDevice::setSpeed(int speed)
{
	if(this->_crossDevice)
	{
		this->_crossDevice->setSpeed(speed);
	}
}

void RgblinkDevice::setParity(char parity)
{
	if(this->_crossDevice)
	{
		this->_crossDevice->setParity(parity);
	}
}

	
void RgblinkDevice::receive_buffer(BYTE *buffer, int len)
{
	int i;
	for(i=0; i<len; i++)
	{
		pipe_write(this->device_pipe, buffer[i]);
	}
}
int RgblinkDevice::readBuf(char * buf, int bufSize)
{
	if(this->_crossDevice)
	{
		return this->_crossDevice->readBuf(buf, bufSize);
	}
	return 0;
}

int RgblinkDevice::readBufAndWritePipe(char *buf, int bufSize)
{
	if(this->_crossDevice)
	{
		int res = this->_crossDevice->readBuf(buf, bufSize);
		if(res)
		{
			this->receive_buffer((BYTE*)buf, res);
		}
		return res;
	}
	return 0;
}

int RgblinkDevice::writeBuf(char * buf, int bufSize)
{
	if(this->_crossDevice)
	{
		return this->_crossDevice->writeBuf(buf, bufSize);
	}
	return 0;
}

void RgblinkDevice::task(void)
{
	Task_RGBlinkProtocol(this->device_Protocol);
}
int RgblinkDevice::send(int add, int cmd, int dat1, int dat2, int dat3, int dat4)
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	if(this->device_Protocol->isConnect[add])
	{
		return SendCmd_RGBlinkProtocol(this->device_Protocol,add,cmd,dat1,dat2,dat3,dat4);
	}
	else
	{
		return SendCmdNoWait_RGBlinkProtocol(this->device_Protocol,add,cmd,dat1,dat2,dat3,dat4);
	}
}
int RgblinkDevice::sendAndWait(int add, int cmd, int dat1, int dat2, int dat3, int dat4)
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	return SendCmdAndWait_RGBlinkProtocol(this->device_Protocol,add,cmd,dat1,dat2,dat3,dat4);
}

int RgblinkDevice::sendCmdIsAck(int add)
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	return SendCmdIsAck_RGBlinkProtocol(this->device_Protocol,add);
}

int RgblinkDevice::sendNoWait(int add, int cmd, int dat1, int dat2, int dat3, int dat4)
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	return SendCmdNoWait_RGBlinkProtocol(this->device_Protocol,add,cmd,dat1,dat2,dat3,dat4);
}

int RgblinkDevice::sendCmd(int add, Command_TypeDef *cmd)
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	if(this->device_Protocol->isConnect[add])
	{
		return SendCmd_RGBlinkProtocol(this->device_Protocol,add,cmd->command,cmd->data_1,cmd->data_2,cmd->data_3,cmd->data_4);
	}
	else
	{
		return SendCmdNoWait_RGBlinkProtocol(this->device_Protocol,add,cmd->command,cmd->data_1,cmd->data_2,cmd->data_3,cmd->data_4);
	}
}
int RgblinkDevice::sendCmdAndWait(int add, Command_TypeDef *cmd)
{
	#if 1

    if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}

	SendCmdNoWait_RGBlinkProtocol(this->device_Protocol,add,cmd->command,cmd->data_1,cmd->data_2,cmd->data_3,cmd->data_4);
	
	if(this->device_Protocol->isConnect[add])
	{
		if(WaitAck_RgblinkProtocol(this->device_Protocol,add, 3000) == FALSE)
		{
			return FALSE;
		}
	}
	else
	{
		if(WaitAck_RgblinkProtocol(this->device_Protocol, add, 2000) == FALSE)
		{
			return FALSE;
		}
	}

	return this->device_Protocol->receiveCmd[add][CMD_INDEX_DAT1]+
	(this->device_Protocol->receiveCmd[add][CMD_INDEX_DAT2]<<8)+
	(this->device_Protocol->receiveCmd[add][CMD_INDEX_DAT3]<<16)+
	(this->device_Protocol->receiveCmd[add][CMD_INDEX_DAT4]<<24);

#else

	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	if(this->device_Protocol->isConnect[add])
	{
		return SendCmdAndWait_RGBlinkProtocol(this->device_Protocol,add,cmd->command,cmd->data_1,cmd->data_2,cmd->data_3,cmd->data_4);
	}
	else
	{
		return SendCmdAndWait_RGBlinkProtocol(this->device_Protocol,add,cmd->command,cmd->data_1,cmd->data_2,cmd->data_3,cmd->data_4);
	}

#endif
}
int RgblinkDevice::sendCmdAndDataBlock(int add, Command_TypeDef *cmd, char *buffer, int size) // size 包括checksum
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	return SendCmdAndDataBlock_RGBlinkProtocol(this->device_Protocol,add,cmd->command,cmd->data_1,cmd->data_2,cmd->data_3,cmd->data_4,
		buffer,size);
}

int RgblinkDevice::waitAck(int add, int timeout)
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	return WaitAck_RgblinkProtocol(this->device_Protocol,add,timeout);
}
int RgblinkDevice::readPipeBuffer( char *buffer, int size, int timeout)
{
	return ReceiveBuffer_RGBlinkProtocol(this->device_Protocol,buffer,size,timeout);
}

int RgblinkDevice::is_connect(int add)
{
	if(add >= MAX_RGBLNK_DEVICE)
	{
		return FALSE;
	}
	return this->device_Protocol->isConnect[add];
}

char *RgblinkDevice::getRemoteIP(void)
{
	if(this->_crossDevice)
	{
		return this->_crossDevice->getRemoteIP();
	}
	return NULL;
}











